namespace Sirius.Mapper.Internals
{
    using System;
    using Exceptions;

    internal class Session : ISession
    {
        private IProviderSession providerSession;
        private readonly IProvider provider;
        private bool rollback;

        public IProvider Provider
        {
            get { return provider; }
        }

        public Session(IProvider provider)
        {
            this.provider = provider;
            
        }

        public void Dispose()
        {
            if(rollback)
            {
                providerSession.Rollback();
            }
            else
            {
                providerSession.Commit();
            }
        }

        public IDataSource ExecuteQuery(IQuery query)
        {
            if(providerSession == null)
            {
                throw new ParameterEmptyException("providerSession");
            }

            if (query == null)
            {
                throw new ArgumentNullException("query");
            }

            return providerSession.ExecuteQuery(query);
        }

        public void Rollback()
        {
            rollback = true;
        }

        public void Accept()
        {
            rollback = false;
        }

        public void AcceptImmediate()
        {
            if (rollback)
            {
                throw new SessionClosedException();
            }

            providerSession.Commit();
            providerSession.Close();

            Open();
        }

        public void Open()
        {
            providerSession = provider.CreateSession();

            if (providerSession == null)
            {
                throw new ParameterEmptyException("providerSession");
            }
        }
    }
}